// Copyright 2012 Google, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef PERREQIPV6ADDRESS__INETSOCKET_H_
#define PERREQIPV6ADDRESS__INETSOCKET_H_

#include <stdint.h>

namespace PerRequestIPv6Address {

class InetSocket {
 public:
  InetSocket();
  InetSocket(int fd);

  // Automatically closes the file descriptor.
  ~InetSocket();

  InetSocket & operator=(int fd);

  bool requestPacketInfo();  // IP_PKTINFO/IPV6_PKTINFO.

  bool enableIPv6Only();  // SOL_IPV6,IPV6_V6ONLY
  bool isIPv6Only();

  bool enableLinuxIPFreebind();  // SOL_IP,IP_FREEBIND

  // SOL_IPV6,IPV6_TRANPARENT -- requires root.
  bool enableLinuxIPTransparent();

  bool enableReuseAddr();  // SOL_SOCKET,SO_REUSEADDR

  // Never use inconsistent TCP URG mechanism.  See
  // http://tools.ietf.org/html/rfc6093 for background.
  bool forceOutOfBandInline();  // SOL_SOCKET, SO_OOBINLINE

  int addressFamily() const;
  uint16_t localPort() const;

  // Leaks internals.  :-(
  int fd() { return fd_; }

 private:
  int fd_;
};


bool NewLocalUDPSocket(InetSocket *sock, uint16_t port);
bool NewLocalTCPSocket(InetSocket *sock, uint16_t port);

bool NewUpstreamUDPSocket(InetSocket *sock, uint16_t port);
bool NewUpstreamTCPSocket(InetSocket *sock, uint16_t port);

void TestSendFromRandomSourceAddress(InetSocket *socket);

}  // namespace PerRequestIPv6Address

#endif  // PERREQIPV6ADDRESS__INETSOCKET_H_
